#include "head.h"
u32_t player_flag = 0xffffffff;

/******************************************************************************
	fb_point():	Draw a point on user's display.
			User can set their point's position and color 
			in this function, then it can be displayed on screen.
******************************************************************************/

int fb_point(fb_info my_fb, int x, int y, u32_t color)
{
	u8_t *position = (u8_t *)my_fb.fbmem + ((my_fb.w * y + x) * my_fb.bpp) / 8;	
	switch(my_fb.bpp)
	{
	case 32:	*(position + 3) = color >> 24;
	case 24:	*(position + 2) = color >> 16;
	case 16: 	*(position + 1) = color >> 8;
	case 8: 	*(position + 0)	= color;
			return 0;
	default:
			return -1;
	}
	return -1;
}


/* ****************************************************************************
	fb_circle():	Draw a circle on user's display.
			User can set the radius, color and the position of 
			the center of the circle here, 
			then it can be displayed on screen.
*******************************************************************************/

#if 1
int fb_circle(fb_info my_fb, int x, int y, int len, u32_t color)
{
	int count = 0;
	int i;
	int j;
	int z;

	for(i = -2 * len; i < 2 * len && x > 315 && x < 965 && y > 77 && y < 723 ; i++)
		for(j = -2 * len; j < 2 * len &&x > 315 && x < 965 && y > 77 && y < 723; j++)
			for(z = len; i * i + j * j <= z * z; z--)
			{
				fb_point(my_fb, x+i, y+j, color);
				count++;
			}
        return count;
}

#endif

/* ****************************************************************************
	fb_str_row() 
	fb_str_col():	Draw a straight line on user's display.
			User can set position where it starts,
			the color and the length of it.	
*******************************************************************************/

int fb_str_row(fb_info my_fb, int x, int y, int len, u32_t color)
{
	int i = 0;
	for(; i < len; i++)
		fb_point(my_fb, x + i, y, color);	
	return 0;
}

int fb_str_col(fb_info my_fb, int x, int y, int len, u32_t color)
{
	int i = 0;
	for(; i < len; i++)
		fb_point(my_fb, x, y + i, color);
	return 0;
}

/* ****************************************************************************
	fb_square():	Draw a square on user's display.
			User can set length, width, color and the position of 
			the square, then it can be displayed on screen.
*******************************************************************************/
int fb_square(fb_info my_fb, int x, int y, int len, int width, u32_t color)
{
	fb_str_row(my_fb, x, y, len, color);
	fb_str_col(my_fb, x + len, y, width, color);
	fb_str_col(my_fb, x, y, width, color);
	fb_str_row(my_fb, x, y + width, len, color);	

	return 0;
} 
#if 0
int fb_diagonal(fb_info my_fb, point point_t1, point point_t2, u32_t color)
{
	float k = (point_t2.y - point_t1.y) / (point_t2.x - point_t1.x);
	float b = point_t1.y - k * point_t1.x;
      	int i;	
	for(i = point_t1.x; i < point_t2.x; i++)
		fb_point(my_fb, i, k * i + b, color);
	
	return 0;
}
#endif 

/* ****************************************************************************
	fb_chess_map():	Draw a map of chess on user's display.

*******************************************************************************/

#if 1
int fb_chess_map(fb_info my_fb, int x, int y, int len, u32_t color)
{
	int i = 0;
	int j = 0;
	for(i = my_fb.w / 2; i <= my_fb.w; i++)
	{
		fb_str_col(my_fb, i, 0, my_fb.h, 0x00949449);
		fb_str_col(my_fb, my_fb.w - i, 0, my_fb.h, 0x00949449);
		usleep(1000);
	}
	for(i = 0; i < 3; i++)
		fb_square(my_fb, x - i, y - i, len, len, color);
	
	fb_square(my_fb, x + 40 - 1, y + 40 - 1, len - 80 + 1, len - 80 + 1, color);
	fb_square(my_fb, x + 40 - 2, y + 40 - 2, len - 80 + 3, len - 80 + 3, color);
	fb_str_col(my_fb, x + 40 - 1, y + 40, len - 80 + 1, color);
	
#if 1
	for(j = x + 40; j <= x + len - 40 - 1; j++)
	{
		fb_str_col(my_fb, j, y + 40, len - 80, 0x000c6a300);
		usleep(1000);
	}
#endif
	for(i = 1; i <= 15; i++)
	{
		fb_str_row(my_fb, x + 40, (y + 40) + y * i, len - 80 + 1, color);
		
		fb_str_col(my_fb, x + 40 + y * i, y + 40, len - 80 + 1, color);
		usleep(100000);
	}

	return 0;
}
#endif

int save_chess(fb_info my_fb)
{
	int i = 0;
	int j = 0;
	for(; i < 17; i++)
		for(; j < 17; j++)
		{
			save[i][j].point_t.x = 320 + 40 * j;
			save[i][j].point_t.y = 80 + 40 * i;
		}
}

int fb_chessgo(fb_info my_fb, int x, int y)
{

	if((x - 320)%40 <= 20 && (y - 80)%40 <= 20)
	{
		m_i = (x - 320 - (x - 320)%40)/40;
		m_j = (y - 80 - (y - 80)%40)/40;	
		
		fb_circle(my_fb, x - (x - 320)%40, y - (y - 80)%40, 15, player_flag);

		save[m_i][m_j].is_set = 1;
		save[m_i][m_j].chess = player_flag;
		player_flag = ~ player_flag;
		if(judgewin(m_i, m_j))
			return;
	}
	printf("i = %d j = %d  is_set = %d  color= %d\n", m_i, m_j, save[m_i][m_j].is_set, save[m_i][m_j].chess);
	return player_flag;
}

int fb_chess_play(fb_info my_fb)
{
	int fd;	

	fb_init_mouse(&fd);	
	printf("opened\n");

	u8_t buf[8];
	
	int set_x = my_fb.w / 2;
	int set_y = my_fb.h / 2;

	int min_x;
	int min_y;

	fb_drawcursor(my_fb, set_x, set_y);

	mouse_event_t mouse_event;
 
	
	while(1)
	{
		int n = read(fd, buf, 8);
		if (n != -1)
		{
			mouse_parse(buf,&mouse_event);
			fb_restorecursor(my_fb, set_x, set_y);
			
			printf("x: %d, y: %d\n", set_x, set_y);
			set_x += mouse_event.x;
			set_y += mouse_event.y;

			if(set_x > my_fb.w)
				set_x = my_fb.w - 10;
			if(set_x < 0)
				set_x = 0;

			if(set_y > my_fb.h)
				set_y = my_fb.h;
			if(set_y < 0)
				set_y = 0;

			fb_drawcursor(my_fb, set_x, set_y);

			switch(mouse_event.button)
			{
			case 1:	
				min_x = (set_x - 320)%40;
				min_y = (set_y - 80)%40;

				m_i = (set_x - 320 - min_x)/40;
				m_j = (set_y - 80 - min_y)/40;	
			
				fb_restorecursor(my_fb, set_x, set_y);
				
				if(!save[m_i][m_j].is_set)
					fb_chessgo(my_fb, set_x, set_y);
					
				fb_drawcursor(my_fb, set_x, set_y);
				
				mouse_event.button = 0;
				
				fb_restorecursor(my_fb, set_x, set_y);	
				break;

			case 2:	
				break;
			case 3: 
				mouse_event.button = 0;
				break;

			default:
				mouse_event.button = 0;
				break;
			}	
		}
		usleep(1);
	}
	close(fd);
	return 0;
}
